package com.zxy.ider.ehome.util;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executor;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.x;

import android.R.integer;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Log;

import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.db.converter.ColumnConverter;
import com.lidroid.xutils.db.converter.ColumnConverterFactory;
import com.lidroid.xutils.db.sqlite.ColumnDbType;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.exception.DbException;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.task.PriorityExecutor;
import com.lidroid.xutils.util.LogUtils;
import com.zxy.ider.ehome.bean.DownloadInfo;

public class DownloadManager {

	private List<DownloadInfo> downloadInfoList = new ArrayList<DownloadInfo>();

	private int maxDownloadThread = 3;

	private Context mContext;
	private DbUtils db;

	public DownloadManager(Context appContext) {
		ColumnConverterFactory.registerColumnConverter(HttpHandler.State.class,
				new HttpHandlerStateConverter());
		mContext = appContext;
		db = DbUtils.create(mContext);
		try {
			downloadInfoList = db.findAll(Selector.from(DownloadInfo.class).where("state", "!=", "INSTALLED"));
		} catch (DbException e) {
			LogUtils.e(e.getMessage(), e);
		}
		if (downloadInfoList == null) {
			downloadInfoList = new ArrayList<DownloadInfo>();
		}
	}

	public int getDownloadInfoListCount() {
		return downloadInfoList.size();
	}

	public DownloadInfo getDownloadInfo(int index) {
		return downloadInfoList.get(index);
	}

	public List<DownloadInfo> getDownloadInfoList() {
		return downloadInfoList;
	}

	public void addNewDownload(String did, String url, String fileName,
			long filesize,String target, boolean autoResume,
			boolean autoRename, RequestCallBack<File> callback) {
		Log.i("zxy", "addNewDownload: target=="+target);
		DownloadInfo downloadInfo = new DownloadInfo();
		downloadInfo.setDid(did);
		downloadInfo.setDownloadUrl(url.replace("\\", "/"));
		downloadInfo.setAutoRename(autoRename);
		downloadInfo.setAutoResume(autoResume);
		downloadInfo.setFileName(fileName);
		downloadInfo.setFileSavePath(target);
		downloadInfo.setFileLength(filesize);
		HttpUtils http = new HttpUtils();
		http.configRequestThreadPoolSize(maxDownloadThread);
		//
		//target文件保存到本地的路径
		//autoResume true, // 如果目标文件存在，接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。
		//autoRename false, // 如果从请求返回信息中获取到文件名，下载完成后自动重命名。
//		RequestParams params = new RequestParams();
//		params.setHeader("Content-Length", "1");
		
		HttpHandler<File> handler = http.download(url.replace("\\", "/"),
				target, autoResume, autoRename,
				new DownloadCallBack(downloadInfo, callback)
		);
		downloadInfo.setHandler(handler);
		downloadInfo.setState(handler.getState().toString());
		for (DownloadInfo dli : downloadInfoList) {
			if (dli.getDid().equals(did)) {
				downloadInfoList.remove(dli);
				break;
			}
		}
		downloadInfoList.add(downloadInfo);
		try {
			db.saveOrUpdate(downloadInfo);

		} catch (DbException e) {
			e.printStackTrace();
		}
	}

    //暂停后点击开始下载
	public void resumeDownload(DownloadInfo downloadInfo,
							   final RequestCallBack<File> callback) throws DbException {
		HttpUtils http = new HttpUtils();
		http.configRequestThreadPoolSize(maxDownloadThread);
		HttpHandler<File> handler = http.download(
				downloadInfo.getDownloadUrl(), downloadInfo.getFileSavePath(),
				downloadInfo.isAutoResume(), downloadInfo.isAutoRename(),
				new DownloadCallBack(downloadInfo, callback));
		downloadInfo.setHandler(handler);
		downloadInfo.setState(handler.getState().toString());
		//db.saveOrUpdate(downloadInfo);
	}

    //移除一个下载任务
	public void removeDownload(final String did) throws DbException {
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (DownloadInfo dli : downloadInfoList) {
					if (dli.getDid().equals(did)) {
						downloadInfoList.remove(dli);
						try {
							db.delete(dli);
						} catch (DbException e) {
							e.printStackTrace();
						}
						break;
					}
				}
			}
		});

		
	}
	
    //移除一个下载任务
	public void removeDownload(DownloadInfo downloadInfo) throws DbException {
		HttpHandler<File> handler = downloadInfo.getHandler();
		if (handler != null && !handler.isCancelled()) {
			handler.cancel();
		}
		downloadInfoList.remove(downloadInfo);
		db.delete(downloadInfo);
	}
    //暂停下载
	public void stopDownload(int index) throws DbException {
		DownloadInfo downloadInfo = downloadInfoList.get(index);
		stopDownload(downloadInfo);
	}
	//全部暂停
	public void stopDoenloadAll() throws DbException{
		for(int i =0;i<downloadInfoList.size();i++){
			stopDownload(downloadInfoList.get(i));
		}
	}

	//清空记录
	public void deleteHistory()throws DbException{
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i =0;i<downloadInfoList.size();i++){
					DownloadInfo downloadInfo = downloadInfoList.get(i);
					HttpHandler<File> handler = downloadInfo.getHandler();
					if (handler != null && handler.getState().equals(HttpHandler.State.SUCCESS)) {
						downloadInfoList.remove(downloadInfo);
						try {
							db.delete(downloadInfo);
						} catch (DbException e) {
							e.printStackTrace();
						}
					}

				}
			}
		}).start();

	}
	public void stopDownload(final DownloadInfo downloadInfo) throws DbException {
		new Thread(new Runnable() {
			@Override
			public void run() {
				HttpHandler<File> handler = downloadInfo.getHandler();
				if (handler != null && !handler.isCancelled()) {
					handler.cancel();
				} else {
					downloadInfo.setState(HttpHandler.State.CANCELLED.toString());
				}
				try {
					db.saveOrUpdate(downloadInfo);
				} catch (DbException e) {
					e.printStackTrace();
				}
			}
		}).start();

	}
   //停止所有下载任务
	public void stopAllDownload() throws DbException {
		for (DownloadInfo downloadInfo : downloadInfoList) {
			HttpHandler<File> handler = downloadInfo.getHandler();
			if (handler != null && !handler.isCancelled()) {
				handler.cancel();
			} else {
				downloadInfo.setState(HttpHandler.State.CANCELLED.toString());
			}
		}
		db.saveOrUpdateAll(downloadInfoList);
	}

	public void backupDownloadInfoList() throws DbException {
		for (DownloadInfo downloadInfo : downloadInfoList) {
			HttpHandler<File> handler = downloadInfo.getHandler();
			if (handler != null) {
				downloadInfo.setState(handler.getState().toString());
			}
		}
		db.saveOrUpdateAll(downloadInfoList);
	}

	public int getMaxDownloadThread() {
		return maxDownloadThread;
	}

	public void setMaxDownloadThread(int maxDownloadThread) {
		this.maxDownloadThread = maxDownloadThread;
	}

	private class DownloadCallBack extends RequestCallBack<File> {
		private DownloadInfo downloadInfo;
		private RequestCallBack<File> callBack;

		private DownloadCallBack(DownloadInfo downloadInfo,
				RequestCallBack<File> callBack) {
			this.callBack = callBack;
			this.downloadInfo = downloadInfo;
		}

		@Override
		public Object getUserTag() {
			return callBack.getUserTag();
		}

		@Override
		public void setUserTag(Object userTag) {
			callBack.setUserTag(userTag);
		}

		@Override
		public void onStart() {
			HttpHandler<File> handler = downloadInfo.getHandler();
			if (handler != null) {
				downloadInfo.setState(handler.getState().toString());
			}
			try {
				Log.i("zxy", "onStart: downloadInfo="+downloadInfo.getFileSavePath());
				db.saveOrUpdate(downloadInfo);
			} catch (DbException e) {
				LogUtils.e(e.getMessage(), e);
			}
		}

		@Override
		public void onCancelled() {
			HttpHandler<File> handler = downloadInfo.getHandler();
			if (handler != null) {
				downloadInfo.setState(HttpHandler.State.CANCELLED.toString());
			}
			try {
				db.saveOrUpdate(downloadInfo);
			} catch (DbException e) {
				LogUtils.e(e.getMessage(), e);
			}
			//callBack.onCancelled();
		}

		@Override
		public void onLoading(long total, long current, boolean isUploading) {
				downloadInfo.setState("LOADING");
				if(total >= 0){
					downloadInfo.setFileLength(total);
				}else{
					total = downloadInfo.getFileLength();
				}
				downloadInfo.setProgress(current);
			callBack.onLoading(total, current, isUploading);
		}

		@Override
		public void onSuccess(ResponseInfo<File> responseInfo) {
				downloadInfo.setState("SUCCESS");
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						db.saveOrUpdate(downloadInfo);
					} catch (DbException e) {
						Log.i("zxy", "onSuccess: DbException");
					}
				}
			}).start();

			callBack.onSuccess(responseInfo);
		}

		@Override
		public void onFailure(HttpException error, String msg) {
			HttpHandler<File> handler = downloadInfo.getHandler();
			if (handler != null) {
				downloadInfo.setState(handler.getState().toString());
			}
			callBack.onFailure(error, msg);
		}
	}


	private class HttpHandlerStateConverter implements
			ColumnConverter<HttpHandler.State> {

		@Override
		public HttpHandler.State getFieldValue(Cursor cursor, int i) {
			return HttpHandler.State.valueOf(cursor.getInt(i));
		}

		@Override
		public HttpHandler.State getFieldValue(String fieldStringValue) {
			if (fieldStringValue == null)
				return null;
			return HttpHandler.State.valueOf(fieldStringValue);
		}

		@Override
		public Object fieldValue2ColumnValue(HttpHandler.State fieldValue) {
			return fieldValue.value();
		}

		@Override
		public ColumnDbType getColumnDbType() {
			return ColumnDbType.INTEGER;
		}
	}

	public boolean isExistence(String did) {
		for (DownloadInfo downloadInfo : downloadInfoList) {
			if (downloadInfo.getDid().equals(did)) {
				return true;
			}
		}
		return false;

	}
}
